﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AppServidor
{
    class GraficaMelodia:IGraficarNota
    {

      public  ProgressBar bar;


        private Color[] color_canales = { Color.Black,   Color.Blue,      Color.Red,        Color.Purple, 
                                          Color.Pink,    Color.Yellow,    Color.Green,      Color.Gold, 
                                          Color.Fuchsia, Color.Gainsboro, Color.Honeydew,   Color.IndianRed,
                                          Color.Khaki,   Color.Lavender,  Color.LightCoral, Color.LightSalmon};
        Color color_cuadricula = Color.LightSkyBlue;
        int celda_ = 20;
        private List<Point> points;
        private List<Point>[] canales ;
        
        private int[] times;
        int time;
        int ancho;
        public int Ancho
        {
            get { return ancho; }
            set { ancho = value; }
        }
        int alto;

        public int Alto
        {
            get { return alto; }
            set { alto = value; }
        }
        int ancho_leyenda;
        public int Ancho_Leyenda
        {
            get { return ancho_leyenda; }
            set { ancho_leyenda = value; }
        }
        int alto_leyenda;

        public int Alto_Leyenda
        {
            get { return alto_leyenda; }
            set { alto_leyenda = value; }
        }
        int x_max;

        public int X_max
        {
            get { return x_max; }
            set { x_max = value; }
        }
        int y_max;

        public int Y_max
        {
            get { return y_max; }
            set { y_max = value; }
        }
        Bitmap grafica;
        Bitmap leyenda;

        public Bitmap Leyenda
        {
            get { return leyenda; }
            set { leyenda = value; }
        }
        public Bitmap Grafica
        {
            get { return grafica; }
         
        }
        Graphics graficador;
        public GraficaMelodia(){
            celda_ = 20;
            this.alto_leyenda = 60;
            this.ancho_leyenda = 400;
            this.ancho = 400;
            this.alto = 210;
            this.y_max = 4500;//Hz
           iniciar();
            grafica = new Bitmap(ancho, alto+2);
            graficador = Graphics.FromImage(grafica);
            crear_leyenda();
            this.crear_cuadicula();
        }

        public void crear_leyenda() {
            leyenda = new Bitmap(this.ancho_leyenda, this.alto_leyenda);
            Pen lapiz = new Pen(Color.FromArgb(10, this.color_cuadricula));
            Graphics g = Graphics.FromImage(leyenda);
            //dibujar leyenda
            g.FillRectangle(lapiz.Brush, 0, 0, ancho_leyenda, alto_leyenda);
            int desp = 3;
            int margen_top = 5;
            int tcelda_ = 20;
            for (int i = 0; i < 8; i++)
            {
                Pen lapiz_R = new Pen(color_canales[i]);
                Pen l_tex = new Pen(Color.Black);
                g.FillPie(new SolidBrush(Color.Gray), desp + 2, margen_top + 2, tcelda_, tcelda_, 0, 360);

                g.FillPie(lapiz_R.Brush, desp, margen_top, tcelda_, tcelda_, 0, 360);
                desp = desp + tcelda_;
                g.DrawString("C-" + i, new Font("arial", 8), l_tex.Brush, new PointF(desp + 2, margen_top+5));
                desp = desp + 3+ 6 * 4;
            }
            desp = 2;
            margen_top = 30;
            for (int i = 8; i < 16; i++)
            {
                Pen lapiz_R = new Pen(color_canales[i]);
                Pen l_tex = new Pen(Color.Black);
                g.FillPie(new SolidBrush(Color.Gray), desp + 2, margen_top + 2, tcelda_, tcelda_, 0, 360);
            
                g.FillPie(lapiz_R.Brush, desp, margen_top, tcelda_, tcelda_, 0, 360);
                desp = desp + 20;
                g.DrawString("C-" + i, new Font("arial", 8), l_tex.Brush, new PointF(desp + 2, margen_top+5));
                desp = desp + 3 + 6 * 4;
            }
        
        }

     private void   crear_cuadicula(){
       Pen lapiz  = new Pen(color_cuadricula,1);
       Pen fondo = new Pen(Color.FromArgb(100,color_cuadricula));
       graficador.FillRectangle(fondo.Brush, 0, 0, ancho, alto+2);
            int dividendo=Math.Max(Alto,this.y_max);
            int divisor=Math.Min(Alto,this.y_max);
            celda_=dividendo/divisor;
            for (int i = 0; i < this.ancho; i += celda_) {
                graficador.DrawLine(lapiz, i, 0, i, alto);
            }

            for (int i = 0; i <= this.alto; i += celda_)
            {
                graficador.DrawLine(lapiz, 0,i, ancho, i);
            }

        }
        public void iniciar() {
            canales = new List<Point>[16];
            times = new int[16];
            if (bar != null) {
               
                bar.Maximum = x_max;
               bar.Minimum = 0;
            }
        }
        public void finalizar()
        {
           
            grafica = new Bitmap(ancho, alto+2);
            graficador = Graphics.FromImage(grafica);
            time = 0;
            Pen lapiz;
            this.crear_cuadicula();
            for (int i = 0; i < this.canales.Length; i++) {
                this.points = canales[i];
                Point[] puntos = (points!=null)?points.ToArray():null;
                if (puntos != null && puntos.Length > 0)
                {
                    Point[] aux = new Point[puntos.Length + 2];
                    aux[0] = new Point(puntos[0].X,alto);
                    aux[aux.Length-1]= new Point(puntos[puntos.Length-1].X,alto);
                    int paro=aux.Length-1;
                    for (int j = 1; j < paro; j++) {
                        aux[j] = puntos[j - 1];
                    }
                    

                if ( puntos.Length > 1)
                {

                    lapiz = new Pen(this.color_canales[i], 2);

                     graficador.DrawLines(lapiz, puntos);
                    lapiz = new Pen(Color.FromArgb(50,this.color_canales[i]), 2);
                    graficador.FillPolygon( lapiz.Brush,aux, FillMode.Winding);
                }
                }
            
            }
        }
        public void graficar(float frecuencia, int duracion, int canal)
        {
            if (graficador != null) {
                time = times[canal];
                time += duracion;
              
                times[canal] = time;
                int py = (int)(frecuencia * this.alto / this.y_max);
                int px = (int)((time) * this.ancho / this.x_max);
                px = ancho - px;
                 py = alto - py;
                points = canales[canal];
                if (points == null) {
                    points = new List<Point>();
                    canales[canal] = points;
                    points.Add(new Point(ancho,py));
                }
                points.Add(new Point(px , py ));
             
            }
            if (bar != null)
            {
                bar.Increment(duracion);
            }
        }
    }
}
